﻿using Fleck;
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace Server
{
    public class User
    {
        public string name;
        public string pwd;
        public string data;
    }

    public class SaveRev
    {
        public string name;
        public string data;
    }

    public class LoginRev
    {
        public string name;
        public string pwd;
    }

    public class ReadRev
    {
        public string name;
    }

    public class Client
    {
        public IWebSocketConnection sock;
        public string name;
    }

    public class Message
    {
        public enum MessageType
        {
            Login,GetUserList,Save,Read,
        }

        public MessageType type;
        public string data;
    }

    class Program
    {
        public static Dictionary<string, User> users;
        public static string m_userPath;
        public static Dictionary<IWebSocketConnection, Client> clients = new Dictionary<IWebSocketConnection, Client>();

        public static void init(string userPath = "./user.json")
        {
            m_userPath = userPath;
            if (File.Exists(m_userPath))
                users = JsonConvert.DeserializeObject<Dictionary<string, User>>(File.ReadAllText(m_userPath));
            else
            {
                users = new Dictionary<string, User>();
                users.Add("Finch", new User() { name = "Finch", pwd = "HUANGXU", data = "" });
            }
        }

        public static void end()
        {
            File.WriteAllText(m_userPath,JsonConvert.SerializeObject(users));
        }

        public static void Login(IWebSocketConnection client,Message m)
        {
            LoginRev ret = JsonConvert.DeserializeObject<LoginRev>(m.data);
            if (users.ContainsKey(ret.name) && users[ret.name].pwd == ret.pwd)
            {
                clients[client].name = ret.name;
            }
            else
            {

            }
        }

        public static void Save(IWebSocketConnection client, Message m)
        {
            SaveRev ret = JsonConvert.DeserializeObject<SaveRev>(m.data);
            if (users.ContainsKey(ret.name))
            {
                users[ret.name].data = ret.data;
            }
            else
            {
                Console.WriteLine("Write User Data Error");
            }
        }

        public static void Read(IWebSocketConnection client, Message m)
        {
            ReadRev ret = JsonConvert.DeserializeObject<ReadRev>(m.data);
            client.Send(JsonConvert.SerializeObject(new Message() { type = Message.MessageType.Read, data = users[ret.name].data }));
        }

        public static void GetList(IWebSocketConnection client, Message m)
        {
            client.Send(JsonConvert.SerializeObject(new Message() { type = Message.MessageType.GetUserList, data = JsonConvert.SerializeObject(users.Keys) }));
        }

        static void Main(string[] args)
        {
            init();

            FleckLog.Level = LogLevel.Debug;
            var server = new WebSocketServer("ws://127.0.0.1:8339");
            //server.Certificate = new System.Security.Cryptography.X509Certificates.X509Certificate2("cert.pfx","123456");
            server.Start(socket =>
            {
                socket.OnOpen = () =>
                {
                    Console.WriteLine("Open!");
                    clients.Add(socket, new Client() { sock = socket, name = "" });
                };
                socket.OnClose = () =>
                {
                    Console.WriteLine("Close!");
                    clients.Remove(socket);
                };
                socket.OnMessage = message =>
                {
                    Console.WriteLine(message);
                    Message m = JsonConvert.DeserializeObject<Message>(message);
                    switch (m.type)
                    {
                        case Message.MessageType.Login:
                            Login(socket, m);
                            break;
                        case Message.MessageType.GetUserList:
                            GetList(socket, m);
                            break;
                        case Message.MessageType.Save:
                            Save(socket, m);
                            break;
                        case Message.MessageType.Read:
                            Read(socket, m);
                            break;
                        default:
                            break;
                    }
                };
            });

            var input = Console.ReadLine();
            while (input != "exit")
            {
                foreach (var socket in clients.ToList())
                {
                    socket.Value.sock.Send(input);
                }
                input = Console.ReadLine();
            }

            end();
        }
    }
}
